---
title: Authorization Policy
description: Configuration for access control on workloads.
location: https://istio.io/docs/reference/config/security/authorization-policy.html
layout: protoc-gen-docs
generator: protoc-gen-docs
schema: istio.security.v1beta1.AuthorizationPolicy
weight: 20
aliases: [/docs/reference/config/authorization/authorization-policy]
number_of_entries: 8
---
<p>Istio Authorization Policy enables access control on workloads in the mesh.</p>

<p>Authorization policy supports both allow and deny policies. When allow and
deny policies are used for a workload at the same time, the deny policies are
evaluated first. The evaluation is determined by the following rules:</p>

<ol>
<li>If there are any DENY policies that match the request, deny the request.</li>
<li>If there are no ALLOW policies for the workload, allow the request.</li>
<li>If any of the ALLOW policies match the request, allow the request.</li>
<li>Deny the request.</li>
</ol>

<p>Istio Authorization Policy also supports the AUDIT action to decide whether to log requests.
AUDIT policies do not affect whether requests are allowed or denied to the workload.
Requests will be allowed or denied based solely on ALLOW and DENY policies.</p>

<p>A request will be internally marked that it should be audited if there is an AUDIT policy on the workload that matches the request.
A separate plugin must be configured and enabled to actually fulfill the audit decision and complete the audit behavior.
The request will not be audited if there are no such supporting plugins enabled.
Currently, the only supported plugin is the <a href="https://istio.io/latest/docs/reference/config/proxy_extensions/stackdriver/">Stackdriver</a> plugin.</p>

<p>Here is an example of Istio Authorization Policy:</p>

<p>It sets the <code>action</code> to &ldquo;ALLOW&rdquo; to create an allow policy. The default action is &ldquo;ALLOW&rdquo;
but it is useful to be explicit in the policy.</p>

<p>It allows requests from:</p>

<ul>
<li>service account &ldquo;cluster.local/ns/default/sa/sleep&rdquo; or</li>
<li>namespace &ldquo;test&rdquo;</li>
</ul>

<p>to access the workload with:</p>

<ul>
<li>&ldquo;GET&rdquo; method at paths of prefix &ldquo;/info&rdquo; or,</li>
<li>&ldquo;POST&rdquo; method at path &ldquo;/data&rdquo;.</li>
</ul>

<p>when the request has a valid JWT token issued by &ldquo;https://accounts.google.com&rdquo;.</p>

<p>Any other requests will be denied.</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 action: ALLOW
 rules:
 - from:
   - source:
       principals: [&quot;cluster.local/ns/default/sa/sleep&quot;]
   - source:
       namespaces: [&quot;test&quot;]
   to:
   - operation:
       methods: [&quot;GET&quot;]
       paths: [&quot;/info*&quot;]
   - operation:
       methods: [&quot;POST&quot;]
       paths: [&quot;/data&quot;]
   when:
   - key: request.auth.claims[iss]
     values: [&quot;https://accounts.google.com&quot;]
</code></pre>

<p>The following is another example that sets <code>action</code> to &ldquo;DENY&rdquo; to create a deny policy.
It denies requests from the &ldquo;dev&rdquo; namespace to the &ldquo;POST&rdquo; method on all workloads
in the &ldquo;foo&rdquo; namespace.</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 action: DENY
 rules:
 - from:
   - source:
       namespaces: [&quot;dev&quot;]
   to:
   - operation:
       methods: [&quot;POST&quot;]
</code></pre>

<p>The following authorization policy sets the <code>action</code> to &ldquo;AUDIT&rdquo;. It will audit any GET requests to the path with the
prefix &ldquo;/user/profile&rdquo;.</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  namespace: ns1
  name: anyname
spec:
  selector:
    matchLabels:
      app: myapi
  action: audit
  rules:
  - to:
    - operation:
        methods: [&quot;GET&quot;]
        paths: [&quot;/user/profile/*&quot;]
</code></pre>

<p>Authorization Policy scope (target) is determined by &ldquo;metadata/namespace&rdquo; and
an optional &ldquo;selector&rdquo;.</p>

<ul>
<li>&ldquo;metadata/namespace&rdquo; tells which namespace the policy applies. If set to root
namespace, the policy applies to all namespaces in a mesh.</li>
<li>workload &ldquo;selector&rdquo; can be used to further restrict where a policy applies.</li>
</ul>

<p>For example,</p>

<p>The following authorization policy applies to workloads containing label
&ldquo;app: httpbin&rdquo; in namespace bar.</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: policy
 namespace: bar
spec:
 selector:
   matchLabels:
     app: httpbin
</code></pre>

<p>The following authorization policy applies to all workloads in namespace foo.</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: policy
 namespace: foo
spec:
  {}
</code></pre>

<p>The following authorization policy applies to workloads containing label
&ldquo;version: v1&rdquo; in all namespaces in the mesh. (Assuming the root namespace is
configured to &ldquo;istio-config&rdquo;).</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: policy
 namespace: istio-config
spec:
 selector:
   matchLabels:
     version: v1
</code></pre>

<h2 id="AuthorizationPolicy">AuthorizationPolicy</h2>
<section>
<p>AuthorizationPolicy enables access control on workloads.</p>

<p>For example, the following authorization policy denies all requests to workloads
in namespace foo.</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: deny-all
 namespace: foo
spec:
  {}
</code></pre>

<p>The following authorization policy allows all requests to workloads in namespace
foo.</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: allow-all
 namespace: foo
spec:
 rules:
 - {}
</code></pre>

<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="AuthorizationPolicy-selector">
<td><code>selector</code></td>
<td><code><a href="https://istio.io/docs/reference/config/type/workload-selector.html#WorkloadSelector">WorkloadSelector</a></code></td>
<td>
<p>Optional. Workload selector decides where to apply the authorization policy.
If not set, the authorization policy will be applied to all workloads in the
same namespace as the authorization policy.</p>

</td>
<td>
No
</td>
</tr>
<tr id="AuthorizationPolicy-rules">
<td><code>rules</code></td>
<td><code><a href="#Rule">Rule[]</a></code></td>
<td>
<p>Optional. A list of rules to match the request. A match occurs when at least
one rule matches the request.</p>

<p>If not set, the match will never occur. This is equivalent to setting a
default of deny for the target workloads.</p>

</td>
<td>
No
</td>
</tr>
<tr id="AuthorizationPolicy-action">
<td><code>action</code></td>
<td><code><a href="#AuthorizationPolicy-Action">Action</a></code></td>
<td>
<p>Optional. The action to take if the request is matched with the rules.</p>

</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="Rule">Rule</h2>
<section>
<p>Rule matches requests from a list of sources that perform a list of operations subject to a
list of conditions. A match occurs when at least one source, operation and condition
matches the request. An empty rule is always matched.</p>

<p>Any string field in the rule supports Exact, Prefix, Suffix and Presence match:</p>

<ul>
<li>Exact match: &ldquo;abc&rdquo; will match on value &ldquo;abc&rdquo;.</li>
<li>Prefix match: &ldquo;abc*&rdquo; will match on value &ldquo;abc&rdquo; and &ldquo;abcd&rdquo;.</li>
<li>Suffix match: &ldquo;*abc&rdquo; will match on value &ldquo;abc&rdquo; and &ldquo;xabc&rdquo;.</li>
<li>Presence match: &ldquo;*&rdquo; will match when value is not empty.</li>
</ul>

<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="Rule-from">
<td><code>from</code></td>
<td><code><a href="#Rule-From">From[]</a></code></td>
<td>
<p>Optional. from specifies the source of a request.</p>

<p>If not set, any source is allowed.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Rule-to">
<td><code>to</code></td>
<td><code><a href="#Rule-To">To[]</a></code></td>
<td>
<p>Optional. to specifies the operation of a request.</p>

<p>If not set, any operation is allowed.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Rule-when">
<td><code>when</code></td>
<td><code><a href="#Condition">Condition[]</a></code></td>
<td>
<p>Optional. when specifies a list of additional conditions of a request.</p>

<p>If not set, any condition is allowed.</p>

</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="Source">Source</h2>
<section>
<p>Source specifies the source identities of a request. Fields in the source are
ANDed together.</p>

<p>For example, the following source matches if the principal is &ldquo;admin&rdquo; or &ldquo;dev&rdquo;
and the namespace is &ldquo;prod&rdquo; or &ldquo;test&rdquo; and the ip is not &ldquo;1.2.3.4&rdquo;.</p>

<pre><code class="language-yaml">principals: [&quot;admin&quot;, &quot;dev&quot;]
namespaces: [&quot;prod&quot;, &quot;test&quot;]
not_ipblocks: [&quot;1.2.3.4&quot;]
</code></pre>

<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="Source-principals">
<td><code>principals</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of source peer identities (i.e. service account), which
matches to the &ldquo;source.principal&rdquo; attribute. This field requires mTLS enabled.</p>

<p>If not set, any principal is allowed.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Source-not_principals">
<td><code>notPrincipals</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of source peer identities.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Source-request_principals">
<td><code>requestPrincipals</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of request identities (i.e. &ldquo;iss/sub&rdquo; claims), which
matches to the &ldquo;request.auth.principal&rdquo; attribute.</p>

<p>If not set, any request principal is allowed.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Source-not_request_principals">
<td><code>notRequestPrincipals</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of request identities.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Source-namespaces">
<td><code>namespaces</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of namespaces, which matches to the &ldquo;source.namespace&rdquo;
attribute. This field requires mTLS enabled.</p>

<p>If not set, any namespace is allowed.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Source-not_namespaces">
<td><code>notNamespaces</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of namespaces.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Source-ip_blocks">
<td><code>ipBlocks</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of IP blocks, which matches to the &ldquo;source.ip&rdquo; attribute.
Populated from the source address of the IP packet.
Single IP (e.g. &ldquo;1.2.3.4&rdquo;) and CIDR (e.g. &ldquo;1.2.3.0/24&rdquo;) are supported.</p>

<p>If not set, any IP is allowed.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Source-not_ip_blocks">
<td><code>notIpBlocks</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of IP blocks.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Source-remote_ip_blocks">
<td><code>remoteIpBlocks</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of IP blocks, which matches to the &ldquo;remote.ip&rdquo; attribute.
Populated from X-Forwarded-For header or proxy protocol.
To make use of this field, you must configure the numTrustedProxies field of the gatewayTopology under the meshConfig
when you install Istio or using an annotation on the ingress gateway.  See the documentation here:
<a href="https://istio.io/latest/docs/ops/configuration/traffic-management/network-topologies/">Configuring Gateway Network Topology</a>.
Single IP (e.g. &ldquo;1.2.3.4&rdquo;) and CIDR (e.g. &ldquo;1.2.3.0/24&rdquo;) are supported.</p>

<p>If not set, any IP is allowed.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Source-not_remote_ip_blocks">
<td><code>notRemoteIpBlocks</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of remote IP blocks.</p>

</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="Operation">Operation</h2>
<section>
<p>Operation specifies the operations of a request. Fields in the operation are
ANDed together.</p>

<p>For example, the following operation matches if the host has suffix &ldquo;.example.com&rdquo;
and the method is &ldquo;GET&rdquo; or &ldquo;HEAD&rdquo; and the path doesn&rsquo;t have prefix &ldquo;/admin&rdquo;.</p>

<pre><code class="language-yaml">hosts: [&quot;*.example.com&quot;]
methods: [&quot;GET&quot;, &quot;HEAD&quot;]
not_paths: [&quot;/admin*&quot;]
</code></pre>

<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="Operation-hosts">
<td><code>hosts</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of hosts, which matches to the &ldquo;request.host&rdquo; attribute.</p>

<p>If not set, any host is allowed. Must be used only with HTTP.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Operation-not_hosts">
<td><code>notHosts</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of hosts.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Operation-ports">
<td><code>ports</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of ports, which matches to the &ldquo;destination.port&rdquo; attribute.</p>

<p>If not set, any port is allowed.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Operation-not_ports">
<td><code>notPorts</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of ports.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Operation-methods">
<td><code>methods</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of methods, which matches to the &ldquo;request.method&rdquo; attribute.
For gRPC service, this will always be &ldquo;POST&rdquo;.</p>

<p>If not set, any method is allowed. Must be used only with HTTP.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Operation-not_methods">
<td><code>notMethods</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of methods.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Operation-paths">
<td><code>paths</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of paths, which matches to the &ldquo;request.url_path&rdquo; attribute.
For gRPC service, this will be the fully-qualified name in the form of
&ldquo;/package.service/method&rdquo;.</p>

<p>If not set, any path is allowed. Must be used only with HTTP.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Operation-not_paths">
<td><code>notPaths</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of paths.</p>

</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="Condition">Condition</h2>
<section>
<p>Condition specifies additional required attributes.</p>

<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="Condition-key">
<td><code>key</code></td>
<td><code>string</code></td>
<td>
<p>The name of an Istio attribute.
See the <a href="https://istio.io/docs/reference/config/security/conditions/">full list of supported attributes</a>.</p>

</td>
<td>
Yes
</td>
</tr>
<tr id="Condition-values">
<td><code>values</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of allowed values for the attribute.
Note: at least one of values or not_values must be set.</p>

</td>
<td>
No
</td>
</tr>
<tr id="Condition-not_values">
<td><code>notValues</code></td>
<td><code>string[]</code></td>
<td>
<p>Optional. A list of negative match of values for the attribute.
Note: at least one of values or not_values must be set.</p>

</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="Rule-From">Rule.From</h2>
<section>
<p>From includes a list or sources.</p>

<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="Rule-From-source">
<td><code>source</code></td>
<td><code><a href="#Source">Source</a></code></td>
<td>
<p>Source specifies the source of a request.</p>

</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="Rule-To">Rule.To</h2>
<section>
<p>To includes a list or operations.</p>

<table class="message-fields">
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
<th>Required</th>
</tr>
</thead>
<tbody>
<tr id="Rule-To-operation">
<td><code>operation</code></td>
<td><code><a href="#Operation">Operation</a></code></td>
<td>
<p>Operation specifies the operation of a request.</p>

</td>
<td>
No
</td>
</tr>
</tbody>
</table>
</section>
<h2 id="AuthorizationPolicy-Action">AuthorizationPolicy.Action</h2>
<section>
<p>Action specifies the operation to take.</p>

<table class="enum-values">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr id="AuthorizationPolicy-Action-ALLOW">
<td><code>ALLOW</code></td>
<td>
<p>Allow a request only if it matches the rules. This is the default type.</p>

</td>
</tr>
<tr id="AuthorizationPolicy-Action-DENY">
<td><code>DENY</code></td>
<td>
<p>Deny a request if it matches any of the rules.</p>

</td>
</tr>
<tr id="AuthorizationPolicy-Action-AUDIT">
<td><code>AUDIT</code></td>
<td>
<p>Audit a request if it matches any of the rules.</p>

</td>
</tr>
</tbody>
</table>
</section>
